<?php
class User extends AppModel {

	var $name = 'User';
	
	var $actsAs = array(
		'Acl' => array(
			'requester'
		),
		'MultipleValidatable'
	);
	
	/**
	 * ============================================== VALIDATIONS ==============================================
	 */
	/**
	 * Default validation ruleset
	 */
    var $validate = array();
    
	/**
	 * Custom validation rulesets
	 */
	var $validationSets = array(
        'admin_add' => array(
    		  'username' => array(
		    		'usernameRule1' => array(
				        'rule' => array('custom', '/^[a-zA-Z0-9][a-zA-Z0-9\-]{0,61}[a-zA-Z0-9]$/'),
						'required' => true,
						'last' => true
				    ),
		    		'usernameRule2' => array(
			    		'rule' => 'isUnique',
				    	'last' => true
					)
			  ),
			 'password_form' => array(
			  	/**
			  	 * http://stackoverflow.com/questions/1036704/would-this-regular-expression-work
			  	 * 
			  	 * Characters can be a mix of alphabet (capitalized/non-capitalized), numeric, and the following characters:
			  	 * ! @ # $ % ^ & * ( ) _ - + = | [ { } ] ; : ' " , < . > ? /
			  	 * 
			  	 * Bez "\"
			  	 */
	    		'password_formRule1' => array(
	    			'rule' => array('custom', "/^([a-zA-Z0-9!@#$%^&*|()_\-+=\[\]{}:;\"',<.>?\/~`]{6,100})$/"),
			  		'required' => true,
			  		'last' => true
				),
	    		'password_formRule2' => array(
	    			'rule' => array('checkIdenticalFieldValues', 'password_confirm'),
					'last' => true
	    		)
    		 ),
	    	'password_confirm' => array(
			  	/**
			  	 * http://stackoverflow.com/questions/1036704/would-this-regular-expression-work
			  	 * 
			  	 * Characters can be a mix of alphabet (capitalized/non-capitalized), numeric, and the following characters:
			  	 * ! @ # $ % ^ & * ( ) _ - + = | [ { } ] ; : ' " , < . > ? /
			  	 * 
			  	 * Bez "\"
			  	 */
	    		'password_confirmRule1' => array(
	    			'rule' => array('custom', "/^([a-zA-Z0-9!@#$%^&*|()_\-+=\[\]{}:;\"',<.>?\/~`]{6,100})$/"),
    		 		'required' => true,
    		 		'last' => true
				),
	    		'password_confirmRule2' => array(
	    			'rule' => array('checkIdenticalFieldValues', 'password_form'),
					'last' => true
	    		)
	    	),
			  'email' => array(
		    		'emailRule1' => array(
				        //'rule' => array('email', true), // "true" proverka za validen/activen DOMAIN
				        'rule' => array('email'),
						'required' => true,
			  			'last' => true
				    ),
		    		'emailRule2' => array(
			    		'rule' => 'isUnique',
				    	'last' => true
					)
			  ),
	    	'group_id' => array(
	    		'group_idRule1' => array(
					'rule' => array('comparison', '>', 0),
	    			'required' => true,
	    			'last' => true
	    		)
			)
    	),
        'admin_edit' => array(
    		  'username' => array(
		    		'usernameRule1' => array(
				        'rule' => array('custom', '/^[a-zA-Z0-9][a-zA-Z0-9\-]{0,61}[a-zA-Z0-9]$/'),
						'required' => true,
						'last' => true
				    ),
		    		'usernameRule2' => array(
			    		'rule' => 'isUnique',
				    	'last' => true
					)
			  ),
			  'email' => array(
		    		'emailRule1' => array(
				        //'rule' => array('email', true), // "true" proverka za validen/activen DOMAIN
				        'rule' => array('email'),
						'required' => true,
			  			'last' => true
				    ),
		    		'emailRule2' => array(
			    		'rule' => 'isUnique',
				    	'last' => true
					)
			  ),
	    	'group_id' => array(
	    		'group_idRule1' => array(
					'rule' => array('comparison', '>', 0),
	    			'required' => true,
	    			'last' => true
	    		)
			)
    	),
        'admin_edit_with_newpassword' => array(
    		  'username' => array(
		    		'usernameRule1' => array(
				        'rule' => array('custom', '/^[a-zA-Z0-9][a-zA-Z0-9\-]{0,61}[a-zA-Z0-9]$/'),
						'required' => true,
						'last' => true
				    ),
		    		'usernameRule2' => array(
			    		'rule' => 'isUnique',
				    	'last' => true
					)
			  ),
			 'new_password_form' => array(
			  	/**
			  	 * http://stackoverflow.com/questions/1036704/would-this-regular-expression-work
			  	 * 
			  	 * Characters can be a mix of alphabet (capitalized/non-capitalized), numeric, and the following characters:
			  	 * ! @ # $ % ^ & * ( ) _ - + = | [ { } ] ; : ' " , < . > ? /
			  	 * 
			  	 * Bez "\"
			  	 */
	    		'new_password_formRule1' => array(
	    			'rule' => array('custom', "/^([a-zA-Z0-9!@#$%^&*|()_\-+=\[\]{}:;\"',<.>?\/~`]{6,100})$/"),
			  		'required' => true,
			  		'last' => true
				),
	    		'new_password_formRule2' => array(
	    			'rule' => array('checkIdenticalFieldValues', 'new_password_confirm'),
					'last' => true
	    		)
    		 ),
	    	'new_password_confirm' => array(
			  	/**
			  	 * http://stackoverflow.com/questions/1036704/would-this-regular-expression-work
			  	 * 
			  	 * Characters can be a mix of alphabet (capitalized/non-capitalized), numeric, and the following characters:
			  	 * ! @ # $ % ^ & * ( ) _ - + = | [ { } ] ; : ' " , < . > ? /
			  	 * 
			  	 * Bez "\"
			  	 */
	    		'new_password_confirmRule1' => array(
	    			'rule' => array('custom', "/^([a-zA-Z0-9!@#$%^&*|()_\-+=\[\]{}:;\"',<.>?\/~`]{6,100})$/"),
    		 		'required' => true,
    		 		'last' => true
				),
	    		'new_password_confirmRule2' => array(
	    			'rule' => array('checkIdenticalFieldValues', 'new_password_form'),
					'last' => true
	    		)
	    	),
			  'email' => array(
		    		'emailRule1' => array(
				        //'rule' => array('email', true), // "true" proverka za validen/activen DOMAIN
				        'rule' => array('email'),
						'required' => true,
			  			'last' => true
				    ),
		    		'emailRule2' => array(
			    		'rule' => 'isUnique',
				    	'last' => true
					)
			  ),
	    	'group_id' => array(
	    		'group_idRule1' => array(
					'rule' => array('comparison', '>', 0),
	    			'required' => true,
	    			'last' => true
	    		)
			)
    	),
        'edit' => array(
    		  'username' => array(
		    		'usernameRule1' => array(
				        'rule' => array('custom', '/^[a-zA-Z0-9][a-zA-Z0-9\-]{0,61}[a-zA-Z0-9]$/'),
						'required' => true,
						'last' => true
				    ),
		    		'usernameRule2' => array(
			    		'rule' => 'isUnique',
				    	'last' => true
					)
			  ),
			  'email' => array(
		    		'emailRule1' => array(
				        //'rule' => array('email', true), // "true" proverka za validen/activen DOMAIN
				        'rule' => array('email'),
						'required' => true,
			  			'last' => true
				    ),
		    		'emailRule2' => array(
			    		'rule' => 'isUnique',
				    	'last' => true
					)
			  )
    	),
        'edit_with_newpassword' => array(
    		  'username' => array(
		    		'usernameRule1' => array(
				        'rule' => array('custom', '/^[a-zA-Z0-9][a-zA-Z0-9\-]{0,61}[a-zA-Z0-9]$/'),
						'required' => true,
						'last' => true
				    ),
		    		'usernameRule2' => array(
			    		'rule' => 'isUnique',
				    	'last' => true
					)
			  ),
			 'old_password_form' => array(
	    		'old_password_formRule1' => array(
	    			'rule' => array('checkUserOldPassword'),
			  		'required' => true,
					'last' => true
	    		)
    		 ),
			 'new_password_form' => array(
			  	/**
			  	 * http://stackoverflow.com/questions/1036704/would-this-regular-expression-work
			  	 * 
			  	 * Characters can be a mix of alphabet (capitalized/non-capitalized), numeric, and the following characters:
			  	 * ! @ # $ % ^ & * ( ) _ - + = | [ { } ] ; : ' " , < . > ? /
			  	 * 
			  	 * Bez "\"
			  	 */
	    		'new_password_formRule1' => array(
	    			'rule' => array('custom', "/^([a-zA-Z0-9!@#$%^&*|()_\-+=\[\]{}:;\"',<.>?\/~`]{6,100})$/"),
			  		'required' => true,
			  		'last' => true
				),
	    		'new_password_formRule2' => array(
	    			'rule' => array('checkIdenticalFieldValues', 'new_password_confirm'),
					'last' => true
	    		)
    		 ),
	    	'new_password_confirm' => array(
			  	/**
			  	 * http://stackoverflow.com/questions/1036704/would-this-regular-expression-work
			  	 * 
			  	 * Characters can be a mix of alphabet (capitalized/non-capitalized), numeric, and the following characters:
			  	 * ! @ # $ % ^ & * ( ) _ - + = | [ { } ] ; : ' " , < . > ? /
			  	 * 
			  	 * Bez "\"
			  	 */
	    		'new_password_confirmRule1' => array(
	    			'rule' => array('custom', "/^([a-zA-Z0-9!@#$%^&*|()_\-+=\[\]{}:;\"',<.>?\/~`]{6,100})$/"),
    		 		'required' => true,
    		 		'last' => true
				),
	    		'new_password_confirmRule2' => array(
	    			'rule' => array('checkIdenticalFieldValues', 'new_password_form'),
					'last' => true
	    		)
	    	),
			  'email' => array(
		    		'emailRule1' => array(
				        //'rule' => array('email', true), // "true" proverka za validen/activen DOMAIN
				        'rule' => array('email'),
						'required' => true,
			  			'last' => true
				    ),
		    		'emailRule2' => array(
			    		'rule' => 'isUnique',
				    	'last' => true
					)
			  )
    	),
		'login' => array(
    	/*
    	 * automagic na username i password ( ne moje da vkarvame "'required' => true" ili ne6to drugo ..  zaradi automagic-a)
    	 * edinstvenoto koeto ne e automagic e captcha, pravilata na koqto se dobavqt ot $this->addExtraValidationSets()
    	 */
    	),
        'register' => array(
    		  'username' => array(
		    		'usernameRule1' => array(
				        'rule' => array('custom', '/^[a-zA-Z0-9][a-zA-Z0-9\-]{0,61}[a-zA-Z0-9]$/'),
						'required' => true,
						'last' => true
				    ),
		    		'usernameRule2' => array(
			    		'rule' => 'isUnique',
				    	'last' => true
					)
			  ),
			 'password' => array(
			  	/**
			  	 * http://stackoverflow.com/questions/1036704/would-this-regular-expression-work
			  	 * 
			  	 * Characters can be a mix of alphabet (capitalized/non-capitalized), numeric, and the following characters:
			  	 * ! @ # $ % ^ & * ( ) _ - + = | [ { } ] ; : ' " , < . > ? /
			  	 * 
			  	 * Bez "\"
			  	 */
	    		'passwordRule1' => array(
	    			'rule' => array('custom', "/^([a-zA-Z0-9!@#$%^&*|()_\-+=\[\]{}:;\"',<.>?\/~`]{6,100})$/"),
			  		'required' => true,
			  		'last' => true
				),
	    		'passwordRule2' => array(
	    			'rule' => array('checkIdenticalFieldValues', 'password_confirm'),
					'last' => true
	    		)
    		 ),
	    	'password_confirm' => array(
			  	/**
			  	 * http://stackoverflow.com/questions/1036704/would-this-regular-expression-work
			  	 * 
			  	 * Characters can be a mix of alphabet (capitalized/non-capitalized), numeric, and the following characters:
			  	 * ! @ # $ % ^ & * ( ) _ - + = | [ { } ] ; : ' " , < . > ? /
			  	 * 
			  	 * Bez "\"
			  	 */
	    		'password_confirmRule1' => array(
	    			'rule' => array('custom', "/^([a-zA-Z0-9!@#$%^&*|()_\-+=\[\]{}:;\"',<.>?\/~`]{6,100})$/"),
    		 		'required' => true,
    		 		'last' => true
				),
	    		'password_confirmRule2' => array(
	    			'rule' => array('checkIdenticalFieldValues', 'password'),
					'last' => true
	    		)
	    	),
			  'email' => array(
		    		'emailRule1' => array(
				        //'rule' => array('email', true), // "true" proverka za validen/activen DOMAIN
				        'rule' => array('email'),
						'required' => true,
			  			'last' => true
				    ),
		    		'emailRule2' => array(
			    		'rule' => 'isUnique',
				    	'last' => true
					)
			  )
    	),
        'account_recover' => array(
    		  'username' => array(
		    		'usernameRule1' => array(
				        'rule' => array('custom', '/^[a-zA-Z0-9][a-zA-Z0-9\-]{0,61}[a-zA-Z0-9]$/'),
						'required' => true,
						'last' => true
				    ),
		    		'usernameRule2' => array(
			    		'rule' => array('checkUsernameWithEmailBelonging'),
				    	'last' => true
					)
			  ),
			  'email' => array(
		    		'emailRule1' => array(
				        //'rule' => array('email', true), // "true" proverka za validen/activen DOMAIN
				        'rule' => array('email'),
						'required' => true,
			  			'last' => true
				    ),
		    		'emailRule2' => array(
			    		'rule' => array('checkUsernameWithEmailBelonging'),
				    	'last' => true
					)
			  )
    	)
    );
	
    var $captcha_codeResult = false;
    
	//--------------------------- check metodi za 'rule' => array('checkMethodName') opciqta
    function checkIdenticalFieldValues($field=array(), $compareWith=null) {
    	return($this->data[$this->name][$compareWith] === array_shift($field));
    }
    
    function checkCaptcha() {
    	return $this->captcha_codeResult;
    }
    
    function checkUserOldPassword() {
    	$usr = $this->findById($this->data[$this->name]['id']);
    	$old_password_hashed = Security::hash($this->data[$this->name]['old_password_form'], null, true);
    	
    	return($old_password_hashed === $usr['User']['password']);
    }
    
    function checkUsernameWithEmailBelonging() {
    	$usrByUsername = $this->findByUsername($this->data[$this->name]['username']);
    	$usrByEmail = $this->findByEmail($this->data[$this->name]['email']);
    	
    	if(empty($usrByUsername['User']['id']) || empty($usrByEmail['User']['id'])) {
    		return false;
    	} else {
    		return($usrByUsername['User']['id'] === $usrByEmail['User']['id']);
    	}
    }
    
	function checkUserfile_mainPicture_editFieldValue() {
		$userfile = $this->data[$this->name]['userfile_mainPicture_edit']['tmp_name'];
		
		list($width, $height, $type, $attr) = getimagesize($userfile);
		
		if(image_type_to_mime_type($type) != 'image/jpeg') {
			return false;
		} else {
			return true;
		}
	}
    
    function beforeValidate() {
    	if(isset($this->data[$this->name]['userfile_mainPicture_edit']['tmp_name']) && ($this->data[$this->name]['userfile_mainPicture_edit']['tmp_name'] != '')) { 
    		$validations = array(
				'Userfile_mainPictureRule1' => array(
	    			'rule' => array('checkUserfile_mainPicture_editFieldValue'),
					'last' => true
				)
			);
    		
    		$this->validate['userfile_mainPicture_edit'] = $validations;
    	}
    	
    	return true;
    }
	//--------------------------/ check metodi za 'rule' => array('checkMethodName') opciqta
    
	//--------------------------- dobavqme kym validationSets masiva dopylnitelni validacii
    function addExtraValidationSets() {
    	if(Configure::read('MyApp_Users.Settings.captcha_login')) {
    		$this->set_captcha_to_actionname('login');
    	}
        if(Configure::read('MyApp_Users.Settings.captcha_register')) {
    		$this->set_captcha_to_actionname('register');
    	}
		if(Configure::read('MyApp_Users.Settings.captcha_edit')) {
    		$this->set_captcha_to_actionname('edit');
    		$this->set_captcha_to_actionname('edit_with_newpassword');
    	}
        if(Configure::read('MyApp_Users.Settings.captcha_accountRecover')) {
    		$this->set_captcha_to_actionname('account_recover');
    	}
    	
    	if(Configure::read('MyApp_Users.Settings.accountActivation')) {
    		$this->set_isActive_to_actionname('admin_edit');
    		$this->set_isActive_to_actionname('admin_edit_with_newpassword');
    	}
    }
    
    function set_captcha_to_actionname($action = 'none') {
    	$this->validationSets[$action]['captcha_code'] = array();
    	
    	$this->validationSets[$action]['captcha_code']['captcha_codeRule1'] = array(
			'rule' => array('checkCaptcha'),
			'required' => true,
			'last' => true
	    );
    }
    
    function set_isActive_to_actionname($action = 'none') {    	
    	$this->validationSets[$action]['is_active'] = array();
    	
    	$this->validationSets[$action]['is_active']['is_activeRule1'] = array(
			'rule' => array('comparison', '>=', 0),
			'required' => true,
			'last' => true
	    );
    }
	//--------------------------/ dobavqme kym validationSets masiva dopylnitelni validacii
    
	/**
	 * =============================================/ VALIDATIONS ==============================================
	 */
		
	//The Associations below have been created with all possible keys, those that are not needed can be removed
	var $belongsTo = array(
		'Group' => array(
			'className' => 'Group',
			'foreignKey' => 'group_id',
			'conditions' => '',
			'fields' => '',
			'order' => ''
		)
	);
	
	function afterSave($created) {
		if($created) {
			// its a creation
			$id = $this->getLastInsertID();
			$aro = new Aro();
			$aro->updateAll( array('alias'=>'\'User:'.$id.'\''),
			array(  'Aro.model'=>'User',
                                        'Aro.foreign_key'=>$id)
			);
		}
		else {
			// its an edit, we have to update the tree
			$data = $this->read();
			$parent_id = $data['User']['group_id'];
			$aro = new Aro();
			$aro_record = $aro->findByAlias( $this->name.':'.$this->id );
			$parent_record = $aro->findByAlias( 'Group:'.$parent_id );
			if ( !empty( $aro_record ) ) {
				$parent_id = '0';
				if ( !empty( $parent_record ) ) {
					$parent_id = $parent_record['Aro']['id'];
				}
				// just changing parents
				$this->Aro->save(array(
                    'parent_id'		=> $parent_id,
    				'id'			=> $aro_record['Aro']['id']
				));
			}
		}
		
		return true;
	}

	/*
	 * ot http://book.cakephp.org/view/645/Acts-As-a-Requester
	 * Sluji za update na grupata ako sme q promenili
	 */
	/*function afterSave($created) {
	 if (!$created) {
	 $parent = $this->parentNode();
	 $parent = $this->node($parent);
	 $node = $this->node();
	 $aro = $node[0];
	 $aro['Aro']['parent_id'] = $parent[0]['Aro']['id'];
	 $this->Aro->save($aro);
	 }
	 }*/

	function parentNode(){
		// This should be the alias of the parent $model::$id
		$data = $this->read();
		
		// This needs to be unique
		return 'Group:'.$data['User']['group_id'];
	}

	/*
	 * ot http://book.cakephp.org/view/645/Acts-As-a-Requester
	 * Sluji za `alias` v aros tablicata
	 */
	/*function parentNode() {
	 if (!$this->id && empty($this->data)) {
	 return null;
	 }
	 $data = $this->data;
	 if (empty($this->data)) {
	 $data = $this->read();
	 }
	 if (!$data['User']['group_id']) {
	 return null;
	 } else {
	 return array('Group' => array('id' => $data['User']['group_id']));
	 }
	 }*/

}
?>